/*   
 * Copyright (c) 2010-2020 DMGIS Ltd. All Rights Reserved.   
 *   
 * This software is the confidential and proprietary information of   
 * DMGIS. You shall not disclose such Confidential Information   
 * and shall use it only in accordance with the terms of the agreements   
 * you entered into with DMGIS.   
 *   
 */
package com.dmgis.qxfw.utils;

import com.google.common.collect.Lists;
//import com.mongodb.MongoClient;
//import com.mongodb.MongoClientOptions;
import com.mongodb.ClientSessionOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

import com.mongodb.connection.ClusterDescription;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

public class MongoDBUtil<MongoClientOptions> {

	private static final String PLEASE_SEND_IP = "没有传入ip或者端口号";
	private static final String PWD_UN_ERR = "用户账号密码不匹配";
	private static final String PLEASE_INSTANCE_MONGOCLIENT = "请实例化MongoClient";
	private static final String PLEASE_SEND_MONGO_REPOSITORY = "请指定要删除的mongo库";
	private static final String DELETE_MONGO_REPOSITORY_EXCEPTION = "删除mongo库异常";
	private static final String DELETE_MONGO_REPOSITORY_SUCCESS = "批量删除mongo库成功";
	private static final String NOT_DELETE_MONGO_REPOSITORY = "未删除mongo库";
	private static final String DELETE_MONGO_REPOSITORY = "成功删除mongo库：";
	private static final String CREATE_MONGO_COLLECTION_NOTE = "请指定要创建的库";
	private static final String NO_THIS_MONGO_DATABASE = "未找到指定mongo库";
	private static final String CREATE_MONGO_COLLECTION_SUCCESS = "创建mongo库成功";
	private static final String CREATE_MONGO_COLLECTION_EXCEPTION = "创建mongo库错误";
	private static final String NOT_CREATE_MONGO_COLLECTION = "未创建mongo库collection";
	private static final String CREATE_MONGO_COLLECTION_SUCH = "创建mongo库collection：";
	private static final String INSERT_DOCUMEN_EXCEPTION = "插入文档失败";
	private static final String INSERT_DOCUMEN_SUCCESSS = "插入文档成功";
	private static final String COLLECTION_IS_NULL = "documentMongoCollection为空";

	private static final Logger logger = Logger.getLogger(String.valueOf(MongoDBUtil.class));

	private MongoDBUtil() {

	}

	private static class SingleHolder {
		private static MongoDBUtil mongoDBUtil = new MongoDBUtil();
	}

	public static MongoDBUtil instance() {

		return SingleHolder.mongoDBUtil;
	}

	/**
	 * 获取mongoDB连接
	 * 
	 * @param host
	 * @param port
	 * @return
	 */
	public MongoClient getMongoConnect(String host, Integer port) {

		if (StringUtils.isBlank(host) || null == port) {
			logger.info(PLEASE_SEND_IP);
			return null;
		}

		return new MongoClient() {
			@Override
			public MongoDatabase getDatabase(String databaseName) {
				return null;
			}

			@Override
			public ClientSession startSession() {
				return null;
			}

			@Override
			public ClientSession startSession(ClientSessionOptions options) {
				return null;
			}

			@Override
			public void close() {

			}

			@Override
			public MongoIterable<String> listDatabaseNames() {
				return null;
			}

			@Override
			public MongoIterable<String> listDatabaseNames(ClientSession clientSession) {
				return null;
			}

			@Override
			public ListDatabasesIterable<Document> listDatabases() {
				return null;
			}

			@Override
			public ListDatabasesIterable<Document> listDatabases(ClientSession clientSession) {
				return null;
			}

			@Override
			public <TResult> ListDatabasesIterable<TResult> listDatabases(Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public <TResult> ListDatabasesIterable<TResult> listDatabases(ClientSession clientSession, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch() {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch(List<? extends Bson> pipeline) {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(List<? extends Bson> pipeline, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch(ClientSession clientSession) {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(ClientSession clientSession, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch(ClientSession clientSession, List<? extends Bson> pipeline) {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(ClientSession clientSession, List<? extends Bson> pipeline, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ClusterDescription getClusterDescription() {
				return null;
			}


		};
	}

	/**
	 * 获取mongoDB连接
	 * 
	 * @param serverAddress
	 * @param
	 * @return
	 */
	public MongoClient getMongoConnect(ServerAddress serverAddress, MongoCredential credential,
									   MongoClientOptions options) {

		if (null == serverAddress) {
			logger.info(PLEASE_SEND_IP);
			return null;
		}

		if (null == credential) {
			logger.info(PWD_UN_ERR);
			return null;
		}

		return new MongoClient() {
			@Override
			public MongoDatabase getDatabase(String databaseName) {
				return null;
			}

			@Override
			public ClientSession startSession() {
				return null;
			}

			@Override
			public ClientSession startSession(ClientSessionOptions options) {
				return null;
			}

			@Override
			public void close() {

			}

			@Override
			public MongoIterable<String> listDatabaseNames() {
				return null;
			}

			@Override
			public MongoIterable<String> listDatabaseNames(ClientSession clientSession) {
				return null;
			}

			@Override
			public ListDatabasesIterable<Document> listDatabases() {
				return null;
			}

			@Override
			public ListDatabasesIterable<Document> listDatabases(ClientSession clientSession) {
				return null;
			}

			@Override
			public <TResult> ListDatabasesIterable<TResult> listDatabases(Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public <TResult> ListDatabasesIterable<TResult> listDatabases(ClientSession clientSession, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch() {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch(List<? extends Bson> pipeline) {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(List<? extends Bson> pipeline, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch(ClientSession clientSession) {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(ClientSession clientSession, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ChangeStreamIterable<Document> watch(ClientSession clientSession, List<? extends Bson> pipeline) {
				return null;
			}

			@Override
			public <TResult> ChangeStreamIterable<TResult> watch(ClientSession clientSession, List<? extends Bson> pipeline, Class<TResult> tResultClass) {
				return null;
			}

			@Override
			public ClusterDescription getClusterDescription() {
				return null;
			}


		};
	}

	/**
	 * 批量删除mongo库
	 * 
	 * @param mongoClient
	 * @param dbNames
	 * @return
	 */
	public String bulkDropDataBase(MongoClient mongoClient, String... dbNames) {

		if (null == mongoClient)
			return PLEASE_INSTANCE_MONGOCLIENT;

		if (null == dbNames || dbNames.length == 0) {
			return PLEASE_SEND_MONGO_REPOSITORY;
		}
		try {
			Arrays.asList(dbNames).forEach(dbName -> mongoClient.getDatabase(dbName));
			logger.info(DELETE_MONGO_REPOSITORY_SUCCESS);
		} catch (Exception e) {
			e.printStackTrace();
			logger.info(DELETE_MONGO_REPOSITORY_EXCEPTION);
		}
		return dbNames == null ? NOT_DELETE_MONGO_REPOSITORY : DELETE_MONGO_REPOSITORY + String.join(",", dbNames);
	}

	/**
	 * 创建指定database的collection
	 * 
	 * @param mongoClient
	 * @param dbName
	 * @param collections
	 * @return
	 */
	public String createCollections(MongoClient mongoClient, String dbName, String... collections) {

		if (null == mongoClient)
			return PLEASE_INSTANCE_MONGOCLIENT;

		if (null == collections || collections.length == 0) {
			return CREATE_MONGO_COLLECTION_NOTE;
		}

		MongoDatabase mongoDatabase = mongoClient.getDatabase(dbName);
		if (null == mongoDatabase)
			return NO_THIS_MONGO_DATABASE;

		try {
			Arrays.asList(collections).forEach(collection -> mongoDatabase.createCollection(collection));
			logger.info(CREATE_MONGO_COLLECTION_SUCCESS);
			return collections == null ? NOT_CREATE_MONGO_COLLECTION
					: CREATE_MONGO_COLLECTION_SUCH + String.join(",", collections);
		} catch (Exception e) {
			e.printStackTrace();
			logger.info(CREATE_MONGO_COLLECTION_EXCEPTION);
		}

		return null;
	}

	/**
	 * 获取MongoCollection
	 * 
	 * @param mongoClient
	 * @param dbName
	 * @param collection
	 * @return
	 */
	public MongoCollection<Document> getMongoCollection(MongoClient mongoClient, String dbName, String collection) {

		if (null == mongoClient)
			return null;

		if (StringUtils.isBlank(dbName))
			return null;

		if (StringUtils.isBlank(collection))
			return null;

		MongoDatabase mongoDatabase = mongoClient.getDatabase(dbName);

		MongoCollection<Document> collectionDocuments = mongoDatabase.getCollection(collection);

		if (null == collectionDocuments)
			return null;

		return collectionDocuments;
	}

	/**
	 * 插入文档数据
	 * 
	 * @param mongoCollection
	 * @param params
	 */
	public int insertDoucument(final MongoCollection<Document> mongoCollection, final Map<String, Object> params) {
		int flag = 0;
		if (null == mongoCollection)
			return flag;

		try {
			Document document = new Document();
			params.keySet().stream().forEach(field -> document.append(field, params.get(field)));

			List<Document> documents = Lists.newArrayList();
			documents.add(document);
			mongoCollection.insertMany(documents);
			flag = 1;
			logger.info(INSERT_DOCUMEN_SUCCESSS);
		} catch (Exception e) {
			e.printStackTrace();
			flag = 0;
			logger.info(INSERT_DOCUMEN_EXCEPTION);
		}
		return flag;
	}

	/**
	 * 更新文档
	 * 
	 * @param mongoCollection
	 * @param conditionParams
	 * @param updateParams
	 */
	public long  updateDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Object> conditionParams, final Map<String, Object> updateParams) {

		if (null == mongoCollection)
			return -1;

		if (null == conditionParams)
			return -1;

		if (null == updateParams)
			return -1;

		Document conditonDocument = new Document();
		conditionParams.keySet().stream().filter(p -> null != p).forEach(o -> {
			conditonDocument.append(o, conditionParams.get(o));
		});

		Document updateDocument = new Document();
		updateParams.keySet().stream().filter(p -> null != p).forEach(o -> {
			updateDocument.append(o, updateParams.get(o));
		});
		UpdateResult updateResult = mongoCollection.updateMany(conditonDocument, new Document("$set", updateDocument));
		logger.info("成功更新" + updateResult.getModifiedCount() + "条记录");
		return updateResult.getModifiedCount();
	}

	/**
	 * 删除文档
	 * 
	 * @param mongoCollection
	 * @param multiple
	 * @param conditionParams
	 * @return
	 */
	public long deleteDocument(final MongoCollection<Document> mongoCollection, final boolean multiple,
			final Map<String, Object> conditionParams) {

		if (null == mongoCollection)
			return 0;

		if (null == conditionParams)
			return 0;

		Document document = new Document();
		DeleteResult deleteResult = null;
		conditionParams.keySet().stream().filter(p -> null != p).forEach(o -> {
			document.append(o, conditionParams.get(o));
		});

		if (multiple) {
			deleteResult = mongoCollection.deleteMany(document);
		} else {
			// 删除文档第一条
			deleteResult = mongoCollection.deleteOne(document);
		}
		logger.info("成功删除" + deleteResult.getDeletedCount() + "条记录");
		return deleteResult.getDeletedCount();
	}

	/**
	 * 查询文档
	 * 
	 * @param mongoCollection
	 * @param conditionParams
	 * @param limit
	 * @param skip
	 * @param sortParams
	 */
	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
											   final Map<String, Object> conditionParams, final Integer limit, final Integer skip,
											   final Map<String, Integer> sortParams, final Map<String, Integer> gtLtOrOtherParams,
											   final String compareField) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		FindIterable<Document> findIterable = mongoCollection.find(Filters.and(document, compareDocument));

		Document sortDocument = new Document();
		if (null != sortParams && !sortParams.isEmpty()) {
			sortParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					sortDocument.append(k, v);
			});
			findIterable.sort(sortDocument);
		}

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);

		return findIterable.iterator();

	}

	/**
	 * 查询文档
	 * 
	 * @param mongoCollection
	 * @return
	 */
	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		FindIterable<Document> findIterable = mongoCollection.find();

		return findIterable.iterator();

	}

	/**
	 * 查询文档
	 * 
	 * @param mongoCollection
	 * @param conditionParams
	 * @return
	 */
	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Object> conditionParams) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		return mongoCollection.find(Filters.and(document)).iterator();
	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Object> conditionParams, final Integer limit, final Integer skip) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		FindIterable<Document> findIterable = mongoCollection.find(Filters.and(document));

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);
		return findIterable.iterator();
	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection, final Integer limit,
			final Integer skip) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		FindIterable<Document> findIterable = mongoCollection.find();

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);
		return findIterable.iterator();
	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Integer> sortParams, boolean sort) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		FindIterable<Document> findIterable = mongoCollection.find();

		Document sortDocument = new Document();
		if (null != sortParams && !sortParams.isEmpty()) {
			sortParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					sortDocument.append(k, v);
			});
			findIterable.sort(sortDocument);
		}

		return findIterable.iterator();
	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Object> conditionParams, final Integer limit, final Integer skip,
			final Map<String, Integer> sortParams) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		FindIterable<Document> findIterable = mongoCollection.find(Filters.and(document));

		Document sortDocument = new Document();
		if (null != sortParams && !sortParams.isEmpty()) {
			sortParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					sortDocument.append(k, v);
			});
			findIterable.sort(sortDocument);
		}

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);
		return findIterable.iterator();
	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection, final Integer limit,
			final Integer skip, final Map<String, Integer> sortParams) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		FindIterable<Document> findIterable = mongoCollection.find();

		Document sortDocument = new Document();
		if (null != sortParams && !sortParams.isEmpty()) {
			sortParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					sortDocument.append(k, v);
			});
			findIterable.sort(sortDocument);
		}

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);
		return findIterable.iterator();
	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Integer> gtLtOrOtherParams, final String compareField) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		return mongoCollection.find(Filters.and(compareDocument)).iterator();

	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection, final Integer limit,
			final Integer skip, final Map<String, Integer> gtLtOrOtherParams, final String compareField) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		FindIterable<Document> findIterable = mongoCollection.find(compareDocument);

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);

		return findIterable.iterator();

	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection, final Integer limit,
			final Integer skip, final Map<String, Integer> sortParams, final Map<String, Integer> gtLtOrOtherParams,
			final String compareField) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		FindIterable<Document> findIterable = mongoCollection.find(compareDocument);

		Document sortDocument = new Document();
		if (null != sortParams && !sortParams.isEmpty()) {
			sortParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					sortDocument.append(k, v);
			});
			findIterable.sort(sortDocument);
		}

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);

		return findIterable.iterator();

	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Object> conditionParams, final Map<String, Object> gtLtOrOtherParams,
			final String compareField) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		FindIterable<Document> findIterable = mongoCollection.find(Filters.and(document, compareDocument));

		return findIterable.iterator();

	}

	public MongoCursor<Document> queryDocument(final MongoCollection<Document> mongoCollection,
			final Map<String, Object> conditionParams, final Integer limit, final Integer skip,
			final Map<String, Integer> gtLtOrOtherParams, final String compareField) {

		if (null == mongoCollection)
			return null;
		/**
		 * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3.
		 * 通过游标遍历检索出的文档集合
		 */

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		FindIterable<Document> findIterable = mongoCollection.find(Filters.and(document, compareDocument));

		if (null != limit)
			findIterable = findIterable.limit(limit);

		if (null != skip)
			findIterable = findIterable.skip(skip);

		return findIterable.iterator();

	}

	/**
	 * 统计指定表的数量
	 * 
	 * @param documentMongoCollection
	 * @param conditionParams
	 * @param gtLtOrOtherParams
	 * @param compareField
	 * @return
	 */
	public Long countTable(final MongoCollection<Document> documentMongoCollection,
			final Map<String, Object> conditionParams, final Map<String, Integer> gtLtOrOtherParams,
			final String compareField) {

		if (null == documentMongoCollection) {
			logger.info(COLLECTION_IS_NULL);
			return 0L;
		}

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}

		return documentMongoCollection.countDocuments(Filters.and(document, compareDocument));
	}

	/**
	 * 统计指定表的数量
	 * 
	 * @param documentMongoCollection
	 * @param conditionParams
	 * @return
	 */
	public Long countTable(final MongoCollection<Document> documentMongoCollection,
			final Map<String, Object> conditionParams) {

		if (null == documentMongoCollection) {
			logger.info(COLLECTION_IS_NULL);
			return 0L;
		}

		Document document = new Document();
		if (null != conditionParams && !conditionParams.isEmpty()) {

			conditionParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					document.append(k, v);
			});
		}

		return documentMongoCollection.countDocuments(Filters.and(document));
	}

	/**
	 * 统计指定表的数量
	 * 
	 * @param documentMongoCollection
	 * @param gtLtOrOtherParams
	 * @param compareField
	 * @return
	 */
	public Long countTable(final MongoCollection<Document> documentMongoCollection,
			final Map<String, Integer> gtLtOrOtherParams, final String compareField) {

		if (null == documentMongoCollection) {
			logger.info(COLLECTION_IS_NULL);
			return 0L;
		}

		Document compareDocument = null;
		if (null != gtLtOrOtherParams && !gtLtOrOtherParams.isEmpty()) {

			Document gtOrLtDoc = new Document();
			gtLtOrOtherParams.forEach((k, v) -> {
				if (StringUtils.isNotBlank(k))
					gtOrLtDoc.append(k, v);
			});
			compareDocument = new Document(compareField, gtOrLtDoc);
		} else {
			compareDocument = new Document();
		}
		return documentMongoCollection.countDocuments(Filters.and(compareDocument));
	}
}